{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "98f9990c",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "b1906b2a",
   "metadata": {},
   "source": [
    "# 函数  \n",
    "\n",
    "## 函数的定义\n",
    "> 1.数学：     f（x）=ax+b  \n",
    "> 2.python: def fib(x) :   \n",
    "> 3.编程思维 VS 数学思维  \n",
    ">> 1.函数可以被定义名称，定义的关键词 <font style=\"color:red\"> **def** </font>\n",
    ">> 2.数学思维是卸载同一行(定义函数 和 运算公式)，面向对象编程中 函数写多行，定义函数为单独一行  \n",
    ">> 3.数学函数一般没有注释，而编程过程中，一般需要对函数进行注释描述，(docstring，课本p151)  \n",
    ">> 4.在数学中：ax + b 是计算公式，而编程中，我们将函数的内容成为**函数体** ，函数体要有一定的**缩进**  \n",
    ">> 5.数学函数执行，将参数带入公式，编程中函数执行，将参数带入函数体\n",
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d09b4b4d",
   "metadata": {},
   "source": [
    "# 关于函数的更多定义\n",
    "\n",
    "## 函数的参数  \n",
    "> 1.形式函数   \n",
    "> 2.实际函数  \n",
    "> 3.默认函数  \n",
    "> 4,位置函数  \n",
    "> 5.关键字参数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7b927a54",
   "metadata": {},
   "source": [
    "# 函数的定义\n",
    "\n",
    "## 定义函数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "67cdf5e9",
   "metadata": {},
   "source": [
    "def：定义函数的关键字  \n",
    "flb： 函数名  \n",
    "(n)：定义函数的参数  \n",
    "\"\"\" \"\"\":文档描述 ： 与使用者进行 交互的唯一途径    \n",
    "代码块：\n",
    "    a,b = 0,1  \n",
    "    while a < n:  \n",
    "        print(a,end=' ')  \n",
    "        a, b = b, a+b  \n",
    "    print()  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "21378623",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 斐波那契数列：0 1 1 2 3 5 8 13 21 34..\n",
    "def fib(x):\n",
    "    \"\"\"列出指定以内的斐波那契数列\"\"\"\n",
    "    a,b = 0,1\n",
    "    while a < x : \n",
    "        print(a,end=\" \")\n",
    "        a,b = b, a+b "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "4e4350ca",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 1 2 3 5 8 13 21 34 55 89 "
     ]
    }
   ],
   "source": [
    "fib(100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "8a968e5b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 实践： 请大学写一个函数，这个函数可以打印“你好，XXX同学”\n",
    "def hello(name):\n",
    "    \"\"\"显示问候语\"\"\"\n",
    "    print(\"hello,Dear %s~\"%(name))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6c3fb58e",
   "metadata": {},
   "source": [
    "## 调用函数/使用函数\\\n",
    "\n",
    "> 1.函数名(参数)  \n",
    "> 2.参数可以不存在  \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 122,
   "id": "9cf9d08b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello,Dear lihua~\n"
     ]
    }
   ],
   "source": [
    "hello(\"lihua\") "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 131,
   "id": "ab3bb102",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "def hi(): \n",
    "    \"\"\"不输入x值的函数\"\"\"\n",
    "    print(\"hi，world!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 126,
   "id": "96bb2c40",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on function hi in module __main__:\n",
      "\n",
      "hi(name)\n",
      "    不输入x值的函数\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help (hi)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 132,
   "id": "5524457c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hi，world!\n"
     ]
    }
   ],
   "source": [
    "hi()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 138,
   "id": "02c047c9",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 回顾与思考\n",
    "import time"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 139,
   "id": "641d9e79",
   "metadata": {},
   "outputs": [],
   "source": [
    "# sleep()需要给定一个时间(int)参数  \n",
    "time.sleep(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 141,
   "id": "e85529df",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "time.struct_time(tm_year=2021, tm_mon=12, tm_mday=2, tm_hour=14, tm_min=51, tm_sec=0, tm_wday=3, tm_yday=336, tm_isdst=0)"
      ]
     },
     "execution_count": 141,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#localtime() 不需要给定参数  \n",
    "time.localtime()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 142,
   "id": "572e3f06",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on built-in function localtime in module time:\n",
      "\n",
      "localtime(...)\n",
      "    localtime([seconds]) -> (tm_year,tm_mon,tm_mday,tm_hour,tm_min,\n",
      "                              tm_sec,tm_wday,tm_yday,tm_isdst)\n",
      "    \n",
      "    Convert seconds since the Epoch to a time tuple expressing local time.\n",
      "    When 'seconds' is not passed in, convert the current time instead.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(time.localtime)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1c178fe3",
   "metadata": {},
   "source": [
    "> 3. 函数的优势\n",
    ">> 1.可以重复使用相同的功能，避免重复造轮子  \n",
    ">> 2.使用者可以不了解函数本身，只需要清楚如何使用即可  \n",
    ">> 3.使用、调用方便，只需要清楚传递的函数和参数  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2663453c",
   "metadata": {},
   "source": [
    "# 函数的参数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "22e445e3",
   "metadata": {},
   "source": [
    "> 形式参数(形参):形式参数,不是实际存在的,是虚拟变量.在定义函数和函数体的时候使用形参,目的是在函数调用时接收实参  \n",
    ">> 1.定义函数的时候定义的参数  \n",
    ">> 2.形式参数不占内存  \n",
    "\n",
    "> 2. 实际参数（实参）:实际参数,调用函数时传递给函数的参数,可以是常量,变量,表达式,函数,传给形参  \n",
    ">> 1. 在**调用**函数的时候传递的参数  \n",
    ">> 2. 调用函数时，形式参数分配空间，传递实际参数，执行函数内存  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "id": "54310c03",
   "metadata": {},
   "outputs": [],
   "source": [
    "def hello(name):\n",
    "    \"\"\"显示问候语\"\"\"\n",
    "    print(\"hello,Dear %s~\"%(name))\n",
    "    \n",
    "#     name即是形参"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "id": "12dfb49d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 以下案例中：\n",
    "# 形式参数为word\n",
    "# 实际参数为wasfdhjgkcjksajdfhgcnmvhFZ"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 145,
   "id": "851a7898",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 课本函数实践案例  \n",
    "def searchvowels(word):\n",
    "    \"\"\"显示元音字母有哪些\n",
    "    \n",
    "    word是文本信息,请输入正确的文本给word\n",
    "    \"\"\"\n",
    "    vowels = set(\"aeiou\")\n",
    "    word = set(word)\n",
    "    print(vowels & word)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 146,
   "id": "dfc1d36b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'a'}\n"
     ]
    }
   ],
   "source": [
    "searchvowels(\"wasfdhjgkcjksajdfhgcnmvhFZ\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 147,
   "id": "c713c4ef",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on function searchvowels in module __main__:\n",
      "\n",
      "searchvowels(word)\n",
      "    显示元音字母有哪些\n",
      "    \n",
      "    word是文本信息,请输入正确的文本给word\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(searchvowels)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6908100a",
   "metadata": {},
   "source": [
    "* 在多个参数的情境下\n",
    "> 1.位置参数 (position argument) \n",
    ">> 1.在形式参数的定义中，有一定的先后顺序  \n",
    ">> 2.在调用函数时，要考虑形参的先后顺序   \n",
    ">> 3.调用函数时，不仅要考虑参数位置，还需要考虑形式参数的个数    \n",
    "\n",
    "> 2.关键词参数  \n",
    ">> 1.在调用函数时，关键字参可以不考虑形式参数的位置  \n",
    "\n",
    "> 3.默认参数  \n",
    ">> 1.调用函数时，可以省略传递的参数信息  \n",
    ">> 2.调用函数时，如果给默认参数赋值，会替换默认参数的结果     "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 166,
   "id": "8753ef45",
   "metadata": {},
   "outputs": [],
   "source": [
    "def  describe_pet( pet_name, animal_type):\n",
    "    \"\"\"显示宠物信息\"\"\"\n",
    "    print(\"\\nI have a \" + animal_type + \".\")\n",
    "    print(\"My \"+animal_type + \"'s name is \"+  pet_name.title() + \".\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 167,
   "id": "c0ac5a18",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a dog.\n",
      "My dog's name is 郭斯文.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(\"郭斯文\",\"dog\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 168,
   "id": "729b7e2c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a python.\n",
      "My python's name is Gaoshu.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(pet_name=\"gaoshu\",animal_type=\"python\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 169,
   "id": "b0a7dd37",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a cat.\n",
      "My cat's name is 微积分.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(animal_type=\"cat\",pet_name=\"微积分\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a957bf33",
   "metadata": {},
   "source": [
    "* 参数注意事项实践  \n",
    "> 1.位置参数和关键字参数同时使用  \n",
    ">> 1. positional argument follows keyword argument(关键字参数<font style=\"color:red\">)均</font>应该挡在位置参数之后）  \n",
    ">> 2. 只要满足1的条件，剩余关键字参数（多个）不考虑 先后顺序  \n",
    "\n",
    "> 2. 非默认参数和默认参数同时使用的时候(定义函数)    \n",
    ">> 1.non-default argument follows defaults argument (默认参数<font style=\"color:red\">)均</font>应该放在非默认参数之后)  \n",
    ">> 2.只要满足1的条件，剩余剩余关键字参数（多个）不考虑 先后顺序  \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "id": "3a0851b3",
   "metadata": {},
   "outputs": [],
   "source": [
    "def test(x,y,z):\n",
    "    \"\"\"打印x,y,z的结果\"\"\"\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "id": "8358ddbe",
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "positional argument follows keyword argument (<ipython-input-106-0b53fb2c91c5>, line 2)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-106-0b53fb2c91c5>\"\u001b[1;36m, line \u001b[1;32m2\u001b[0m\n\u001b[1;33m    test(5,y=3,2)\u001b[0m\n\u001b[1;37m               ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m positional argument follows keyword argument\n"
     ]
    }
   ],
   "source": [
    "# 实践一：\n",
    "test(5,y=3,2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 112,
   "id": "2292f758",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5\n",
      "3\n",
      "2\n"
     ]
    }
   ],
   "source": [
    "# 实践二：\n",
    "test(5,3,z = 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "id": "0739da76",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5\n",
      "3\n",
      "2\n"
     ]
    }
   ],
   "source": [
    "# 实践3 ：\n",
    "test(5,z = 2,y=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 171,
   "id": "33332d49",
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "non-default argument follows default argument (<ipython-input-171-eac1f1ed18cb>, line 2)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-171-eac1f1ed18cb>\"\u001b[1;36m, line \u001b[1;32m2\u001b[0m\n\u001b[1;33m    def test(x,y=1,z):\u001b[0m\n\u001b[1;37m             ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m non-default argument follows default argument\n"
     ]
    }
   ],
   "source": [
    "# 测试2：\n",
    "def test(x,y=1,z):\n",
    "    \"\"\"打印x,y,z的结果\"\"\"\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 172,
   "id": "0edd991c",
   "metadata": {},
   "outputs": [],
   "source": [
    "def test(x,z,y=1):\n",
    "    \"\"\"打印x,y,z的结果\"\"\"\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d4259925",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
